﻿----------------------------
--[[ Loot client module ]]--
----------------------------

local AddonParent = LibStub("AceAddon-3.0"):GetAddon("MLV");
local module = AddonParent:NewModule("LootClient");


function module:OnInitialize()
        AddonParent:GetModule("CommHandler"):Embed(self);
end


function module:OnEnable()
        self:RegisterMessage("RollingLoot");
        self:RegisterMessage("ValidateRoll");

        self.freezeLooting = false;
        self.waiting = {};
        self.slots = {};
        self.items = {};
end


function module:OnDisable()
end


----------
-- Callback method which start looting process.
--
-- @event   "RollingLoot"
-- @sender  emitter of the command
-- @...     items ID
----------
function module:RollingLoot(event, sender, timeout, ...)
        self.freezeLootFrame = true;
        for k, itemId in pairs(...) do
                local nfo = { requirer = sender, index = 0, itemId = itemId, timeout = timeout };
                local key = self:LootKey(nfo);
                self.waiting[key] = nfo;
        end
        self:ProcessQueuedItems();
        self.freezeLootFrame = false;
end


function module:ValidateRoll(frm, choice)
        local nfo = frm.nfo;
        local key = self:LootKey(nfo);
        self.items[key] = nil;
        self.slots["slot"..nfo.index] = nfo.index;
        self:SendToWhisper(nfo.receiver, "LootRollResult", nfo.itemId, choice);
        self:ProcessQueuedItems();
end


----------
-- Calculate unique key for looting item.
--
-- @nfo   item loot information
----------
function module:LootKey(nfo)
        return nfo.requirer.."."..nfo.itemId;
end


----------
-- ...
----------
function module:ProcessQueuedItems()
        for key, nfo in pairs(self.waiting) do
                if self.items[key] then
                        self.items[key]:ResetTimer();
                else
                        local slot, idx = next(self.slots);
                        if slot then
                                self:ShowItem(idx, nfo);
                        end
                end
        end
end


----------
-- ...
--
-- @idx   slot index
-- @nfo   loot item information
----------
function module:ShowItem(idx, nfo)
        if idx > 0 and nfo then
                self.slots["slot"..idx] = nil;
                nfo.index = idx;

                local frm = MLVLootFrame:Create(idx, nfo);
                frm:Show();

                local key = self:LootKey(nfo);
                self.items[key] = frm;
                self.waiting[key] = nil;
        end
end




---------------------------------------
--[[       Loot client frame       ]]--
---------------------------------------

local frame = AddonParent:New("LootClientFrame");

function frame:OnInitialize()
        AddonParent:GetModule("CommHandler"):Embed(self);
end


function frame:Create(idx, nfo)
        local lootFrame = getglobal(AddonPrefix.."LootFrame"..idx);
        if lootFrame == nil then
                lootFrame = CreateFrame("Frame", AddonPrefix.."LootFrame"..idx, UIParent, "GroupLootFrameTemplate");
                if idx == 1 then
                        lootFrame:SetPoint("BOTTOMRIGHT", -40, 150);
                else
                        lootFrame:SetPoint("BOTTOMRIGHT", getglobal(AddonPrefix.."LootFrame"..(idx - 1)), "TOPRIGHT", 0, 15);
                end
                function lootFrame:ResetTimer() self.time = GetTime(); end;
                lootFrame:SetScript("OnShow", frame.OnShow);
                getglobal(AddonPrefix.."LootFrame"..idx.."Timer"):SetScript("OnUpdate", frame.OnUpdateTimer);
                getglobal(AddonPrefix.."LootFrame"..idx.."PassButton"):SetScript("OnClick", frame.OnClickPassButton);
                getglobal(AddonPrefix.."LootFrame"..idx.."GreedButton"):SetScript("OnClick", frame.OnClickGreedButton);
                getglobal(AddonPrefix.."LootFrame"..idx.."RollButton"):SetScript("OnClick", frame.OnClickRollButton);
                getglobal(AddonPrefix.."LootFrame"..idx.."IconFrame"):SetScript("OnEnter", frame.OnEnterIconFrame);
                getglobal(AddonPrefix.."LootFrame"..idx.."IconFrame"):SetScript("OnClick", frame.OnClickIconFrame);
                getglobal(AddonPrefix.."LootFrame"..idx.."IconFrame"):SetScript("OnUpdate", frame.OnUpdateIconFrame);
        end
        lootFrame.nfo = nfo;
        lootFrame.time = GetTime();
        getglobal(AddonPrefix.."LootFrame"..idx.."Timer"):SetMinMaxValues(0, nfo.timeout);
        return lootFrame;
end


function frame:OnShow(...)
        local name, link, quality, iLevel, reqLevel, type, subType, maxStack, equipSlot, texture = GetItemInfo(self.itemId);
       
        self:SetBackdrop({bgFile = "Interface\\DialogFrame\\UI-DialogBox-Gold-Background", edgeFile = "Interface\\DialogFrame\\UI-DialogBox-Gold-Border", tile = true, tileSize = 32, edgeSize = 32, insets = { left = 11, right = 12, top = 12, bottom = 11 } } );
        getglobal(self:GetName().."Corner"):SetTexture("Interface\\DialogFrame\\UI-DialogBox-Gold-Corner");
        getglobal(self:GetName().."Decoration"):Show();
       
        --      self:SetBackdrop({bgFile = "Interface\\DialogFrame\\UI-DialogBox-Background", edgeFile = "Interface\\DialogFrame\\UI-DialogBox-Border", tile = true, tileSize = 32, edgeSize = 32, insets = { left = 11, right = 12, top = 12, bottom = 11 } } );
        --      getglobal(self:GetName().."Corner"):SetTexture("Interface\\DialogFrame\\UI-DialogBox-Corner");
        --      getglobal(self:GetName().."Decoration"):Hide();
       
        getglobal(self:GetName().."IconFrameIcon"):SetTexture(texture);
        getglobal(self:GetName().."Name"):SetText(name);
        local color = ITEM_QUALITY_COLORS[quality];
        getglobal(self:GetName().."Name"):SetVertexColor(color.r, color.g, color.b);
end

----------
-- ...
--
-- @elapsed : time in second since last update
----------
function frame:OnUpdateTimer(...)
        if not module.freezeLootFrame then
                local min, max = self:GetMinMaxValues();
                local elapsed = GetTime() - self:GetParent().time;
                local current = max - elapsed;
                if current < min then
                        self:SetValue(min);
                        self:DoChoice(self:GetParent(), 0);
                else
                        self:SetValue(current);
                end
        end
end


function frame:OnClickPassButton(...)
        frame:DoChoice(self:GetParent(), 0);
end


function frame:OnClickGreedButton(...)
        frame:DoChoice(self:GetParent(), 1);
end


function frame:OnClickRollButton(...)
        frame:DoChoice(self:GetParent(), 2);
end


function frame:DoChoice(frm, choice)
        frm:Hide();
        self:SendMessage("ValidateRoll", frm, choice);
end



function frame:OnEnterIconFrame(...)
        local link = select(2, GetItemInfo(self:GetParent().itemId));
        GameTooltip:SetOwner(self, "ANCHOR_RIGHT");
        GameTooltip:SetHyperlink(link);
        CursorUpdate(self);
end


function frame:OnClickIconFrame(...)
        HandleModifiedItemClick(select(2, GetItemInfo(self:GetParent().itemId)));
end


function frame:OnUpdateIconFrame(...)
        if GameTooltip:IsOwned(self) then
          GameTooltip:SetOwner(self, "ANCHOR_RIGHT");
          GameTooltip:SetHyperlink(select(2, GetItemInfo(self:GetParent().itemId)));
        end
        CursorOnUpdate(self);
end
